{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# node.js模块——fs模块\n",
    "fs模块用于对系统文件及目录进行读写操作。   \n",
    "支持同步和异步。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 操作文件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 异步读文"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello anlzou\n",
      "\n"
     ]
    }
   ],
   "source": [
    "// 导入 fs 模块\n",
    "var fs = require('fs');\n",
    "\n",
    "fileName = 'test.txt'\n",
    "\n",
    "// 读取文件\n",
    "fs.readFile(fileName, 'utf-8', function(err, data) {\n",
    "    if(err){\n",
    "        console.log(\"找不到“\"+fileName+\"”文件\")\n",
    "    }else{\n",
    "        console.log(data.toString())\n",
    "    }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 同步读取文件\n",
    "不需要在后面使用回调方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello anlzou\n",
      "\n"
     ]
    }
   ],
   "source": [
    "var data = fs.readFileSync(fileName,'utf-8');\n",
    "console.log(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 写入文件   \n",
    "如果文件不存在则创建\n",
    "\n",
    "```js\n",
    "fs.writeFile(\"fileName\",\"写入文件的内容\",{flag:\"a\"},function (err) {})\n",
    "a追加\n",
    "w写入（默认）\n",
    "r（读取）\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "code_folding": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "文件写入成功！\n"
     ]
    }
   ],
   "source": [
    "fileName = 'test/data/test-3.txt'\n",
    "textNull = ''\n",
    "message = 'hello anlzou\\n'\n",
    "\n",
    "fs.writeFile(fileName, message,{flag:'a'}, function(err){\n",
    "    console.log('文件写入成功！')\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 文件修改"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Error: ENOENT: no such file or directory, rename '22.txt' -> 'test.txt'] {\n",
      "  errno: -2,\n",
      "  code: 'ENOENT',\n",
      "  syscall: 'rename',\n",
      "  path: '22.txt',\n",
      "  dest: 'test.txt'\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "// 要修改名字的文件  修改后的名字  回调函数\n",
    "fs.rename(\"22.txt\",\"test.txt\",function (err) {\n",
    "    if(err){\n",
    "        console.log(err);\n",
    "    }else {\n",
    "        console.log(\"修改成功\");\n",
    "    }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 文件删除"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "code_folding": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "删除成功\n"
     ]
    }
   ],
   "source": [
    "// 删除文件\n",
    "fs.unlink(\"test.txt\",function (err) {\n",
    "    if(err){\n",
    "        return console.log(err);\n",
    "    }else {\n",
    "        console.log(\"删除成功\");\n",
    "    }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 文件复制\n",
    "先读取，再复制   \n",
    "如果文件已经存在，则覆盖原来的文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "复制文件成功！\n"
     ]
    }
   ],
   "source": [
    "// 异步方法\n",
    "fs.readFile(fileName, function(err, data){\n",
    "    if(err){\n",
    "        return console.log(err)\n",
    "    }else{\n",
    "        var copyData = data.toString();\n",
    "        fs.writeFile('test-copy', copyData, function(err){\n",
    "            if(err){\n",
    "                return console.log(err);\n",
    "            }else{\n",
    "                console.log('复制文件成功！')\n",
    "            }\n",
    "        })\n",
    "    }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 文件夹操作 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 文件夹创建\n",
    "```\n",
    "1 -- x: 执行\n",
    "2 -- w: 写入\n",
    "4 -- r: 读取\n",
    "7=1+2+4 -- 创建的文件夹可执行可读可写\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "创建成功\n"
     ]
    }
   ],
   "source": [
    "fs.mkdir('test/data',0777,function(err){\n",
    "    if(err){\n",
    "        console.log(err);\n",
    "    }else{\n",
    "        console.log(\"创建成功\");\n",
    "    }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 修改文件夹权限"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "修改ok\n"
     ]
    }
   ],
   "source": [
    "fs.chmod(\"data\",0777,function (err) {\n",
    "    if(err){\n",
    "        return console.log(err);\n",
    "    }else {\n",
    "        console.log(\"修改ok\");\n",
    "    }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 修改文件夹名字，与修改文件是同一个函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test->data\n"
     ]
    }
   ],
   "source": [
    "oldFolderName = 'test'\n",
    "newFolderName = 'data'\n",
    "\n",
    "fs.rename(oldFolderName, newFolderName, function (err) {\n",
    "    if(err){\n",
    "        return console.log(err);\n",
    "    }else {\n",
    "        console.log(oldFolderName+\"->\"+newFolderName);\n",
    "    }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 判断某个文件件是否存在，如果不存在则创建\n",
    "exists函数，是唯一一个回调函数中不带err的回调函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "文件夹创建成功\n"
     ]
    }
   ],
   "source": [
    "folderName = 'test'\n",
    "\n",
    "fs.exists(folderName, function (exists) {\n",
    "    if(exists){\n",
    "        console.log(\"该文件夹已经存在\");\n",
    "    }else {\n",
    "        fs.mkdir(folderName, function (err) {\n",
    "            if(err){\n",
    "                return console.log(err);\n",
    "            }else {\n",
    "                console.log(\"文件夹创建成功\");\n",
    "            }\n",
    "        })\n",
    "    }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 删除文件夹\n",
    "只能删除空的文件夹"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Error: ENOTEMPTY: directory not empty, rmdir 'data'] {\n",
      "  errno: -39,\n",
      "  code: 'ENOTEMPTY',\n",
      "  syscall: 'rmdir',\n",
      "  path: 'data'\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "fs.rmdir(\"test\",function (err) {\n",
    "    if(err){\n",
    "        return console.log(err);\n",
    "    }else {\n",
    "        console.log(\"文件夹删除成功\");\n",
    "    }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 读取文件夹里面的信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\n",
      "  '.ipynb_checkpoints',\n",
      "  'Untitled.ipynb',\n",
      "  'test',\n",
      "  'test-copy',\n",
      "  'test.txt'\n",
      "]\n"
     ]
    }
   ],
   "source": [
    "fs.readdir(\".\",function (err,data) {\n",
    "    if(err){\n",
    "        console.log(err);\n",
    "    }else {\n",
    "        console.log(data);\n",
    "    }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 判断是文件或者是文件夹"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test.txt是文件\n"
     ]
    }
   ],
   "source": [
    "name = 'test.txt'\n",
    "\n",
    "fs.stat(name, function (err,data) {\n",
    "   if(err){\n",
    "       return console.log(err);\n",
    "   }else {\n",
    "       //判断是否是文件\n",
    "       if(data.isFile()){\n",
    "           //是文件\n",
    "           console.log(name + \"是文件\");\n",
    "       }else{\n",
    "           //是文件夹\n",
    "           console.log(name + \"是文件夹\");\n",
    "       }\n",
    "   }\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 删除非空文件夹\n",
    "首先获取到该文件夹里面所有的信息，遍历里面的信息，判断是文件还是文件夹，如果是文件直接删除，如果是文件，进入文件，重复上述过程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test/data\n",
      "test/data/test-3.txt\n",
      "test/data\n",
      "test/test-2.txt\n",
      "test/test.txt\n",
      "test\n"
     ]
    }
   ],
   "source": [
    "function delFile(url) {\n",
    "    var data = fs.readdirSync(url);\n",
    "    for(var i = 0;i < data.length;i++){\n",
    "        // console.log(data[i])\n",
    "        var path = url + \"/\" +data[i];\n",
    "        console.log(path);\n",
    "        var stat = fs.statSync(path);\n",
    "        if(stat.isFile()){\n",
    "            fs.unlinkSync(path);\n",
    "        }else{\n",
    "            delFile(path);\n",
    "        }\n",
    "    }\n",
    "    fs.rmdirSync(url);\n",
    "}\n",
    "delFile(\"test\");"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Javascript (Node.js)",
   "language": "javascript",
   "name": "javascript"
  },
  "language_info": {
   "file_extension": ".js",
   "mimetype": "application/javascript",
   "name": "javascript",
   "version": "13.13.0"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "165px"
   },
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
